Salesforce 認定 Sharing and Visiblity デザイナー 試験の勉強メモ
※Spring '19 の時に書いてるメモです
受験ガイドによると、安全で拡張性の高いセキュリティモデル を構築できるスキルを証明するための資格、だそうです。アプリケーションアーキテクト 資格をとるためには必須となる資格なのですが、どうやって勉強していけば良いのか。。。
上級 Developer を勉強した時には FOCUSONFORCE を利用しましたが、本資格についても参考書と問題集があるようです。課金するかは悩みどころですが、とりあえず置いといて先に進みます。
https://gyazo.com/2d12e57f45ed8f14a5cc0584dbc513d1
試験範囲
まずはじめに 受験ガイド から試験範囲を確認します。
table:試験範囲
宣言的共有 67%
パフォーマンス 8%
プログラミング的共有 25%
え、なんか雑じゃない・・・?ってくらい大雑把な区切りですね。他の試験だと10数パーセントくらいの区切りで分類されてたりするのですが、、、。68% 以上を獲得できたら合格みたいなので、極端な話、宣言的共有の分野を極めればそれだけでほぼ合格できちゃいますね。
受験ガイドに公式の Trailmix が書いてあるのでそこから手をつけていこうと思います。
あと、いつも参考にさせていただいている海外ブログも見ました。
Salesforce Certified Sharing and Visibility Designer Exam Tips
開発者ドキュメント
Trailmix を参考に本試験に関係がありそうなドキュメントを集めてみました。
公式 Trailmix は全部英語なので、なるべく日本語版を載せてます。
ユーザのアクセス権の制御
レコードアクセス権に関連して Salesforce 内部で実行される処理
共有モデルの仕組み
ちょっと古いですけど、こちら のホワイトペーパーもわかりやすかったです。
企業の規模に応じたレコードアクセス権の作成
Apex を使用したレコードの共有
Tips and Hints for Sharing Data
※URL 見るとわかりますが、いわゆるチートシートってやつです。英語のみ。
宣言的共有 (67%)
設定 -> セキュリティ -> 共有
https://gyazo.com/e4a1daa4b63cde64c32eba82d74e71d9
下の方にスクロールしていくと、オブジェクト毎に共有ルールを設定できます。
https://gyazo.com/546900a2b9cec94d1c0da5eb7342aecc
新規 ボタンをクリックすると、共有ルールを設定できる画面が表示されます。この画面で覚えておきたいのは以下の通りです。
共有のルールタイプは レコードの所有者に基づくもの、条件に基づくもの の2種類がある
共有先として選べるのは ロール (3種類、実際の画面で確認してくれ) と、公開グループ
アクセス権は 参照のみ or 参照・更新 のどちらか
こういう場合にはアクセスさせないとかはできない
所有者ベースの共有ルールと、条件ベースの共有ルール
https://gyazo.com/8a4aa4c56d9eac5ed8ab415c482afd13 https://gyazo.com/71fb50d4b7e034a32c33cf50b2ffa931
以下、トピック毎に箇条書きでまとめていきます。
オブジェクトレベル (項目レベル) のアクセス制御
ここらへんは認定アドミンレベルなのであまり調べてません。
項目レベルセキュリティ
プロファイル単位で 設定するやつ
オブジェクトの項目レベルで CRUD 権限を制御できる
権限セット
ユーザ単位で 設定するやつ
注意点:権限セットは 権限を付与するのみ
アクセスさせない (権限を外す) といった用途は不可
レコードレベルのアクセス制御
ここら辺も同様。
所有者ベースの共有
なんでレコードを所有する必要があんの?ってのが書かれた記事 Why Users Should Own Records
所有者を変更できるのは、現在のレコードの所有者、システム管理者、ロール階層の上位者
条件ベースの共有
上に書いた
取引先チーム、商談チーム
標準オブジェクト限定の機能
チームで対応するときに使うやつ
ロール階層がフィットしないケースとか、条件ベース、所有者ベースの共有設定がフィットしないケース
アクセス権が与えられる
グループ/ロール
ロールは階層
https://help.salesforce.com/articleView?id=setup_roles_guidelines.htm&type=5
キュー
キューはユーザ、ロール、公開グループ で構成されるユーザ (メンバ) の集合
所有者としてキューを設定できる
キューが所有者となるレコードのキューメンバは、所有者を自分に割り当てることができる
公式 Trailmix の一番最後の項の Hands-on で出題されているのでそれを見ると理解が深まる
ケースオブジェクトでよく使われる
外部ユーザ(コミュニティとか)
権限レベルは、内部ユーザ > 外部ユーザ (内部ユーザの方が強い)
組織の共有設定
海外ブログとかで OWD (Org Wide Defalt) ってでてきたらこれのこと
オブジェクト毎にデフォルトのアクセス権限をつけることができる
制限したかったら非公開が基本
https://gyazo.com/b27bb0346ce2e77c95421ba2a444f157
標準ページの「共有」ボタン
どういったことができるのか見直す。共有ボタンが表示されなくてハマる人が結構いるみたい
どのユーザ、グループにアクセス権がついてるかの確認にも使える
LEX では表示されないので、使いたかったら Classic に戻す必要がある (対応してほしい)
AppExchange に擬似的に共有ボタンつくるやつが公開されている (らしい)
エンタープライズテリトリー管理
機能概要を一言で書くと、商談オブジェクトに対してテリトリー項目を設定することでテリトリーに紐づいた営業員に商談を割り当てるといったことができる Sales Cloud の機能
https://help.salesforce.com/articleView?id=tm2_intro.htm&type=5
なお、テリトリーの機能は日本ではほとんど使われていない (らしい)・・・
主従関係のオブジェクトのアクセス権限
子へのアクセス権は親に依存させることが可能
だから管理が楽
参照関係のオブジェクトのアクセス権
片方しかアクセス権なかったら見えなくなる
組み込みの共有動作
知らない人が結構いるので見落としがち
取引先オブジェクトとかケースオブジェクトに参照関係を持ってるオブジェクトにアクセス権があると、暗黙的なアクセス権が付与される場合がある
https://help.salesforce.com/articleView?id=sharing_across_objects.htm&type=5&sfdcIFrameOrigin=null
コミュニティユーザとのレコード共有
https://help.salesforce.com/articleView?id=networks_setting_light_users.htm&type=5&sfdcIFrameOrigin=null
共有セット:外部ユーザ向けの権限セット的なやつ
プロファイル設定
めっちゃあって覚えられない (どうすればいいんだ?)
https://gyazo.com/721269eed352598ffc8c8616069ccbbd
所有者を変更した時の影響
手動での共有設定はぜんぶ削除される
https://help.salesforce.com/articleView?id=security_sharing_considerations.htm&type=5&sfdcIFrameOrigin=null
項目アクセス許可
Lightning の UI にて、設定 > セキュリティ > 項目アクセス許可 からアクセスできる。
この項目のプロファイル毎のアクセス権一覧、とか、このプロファイルでこのオブジェクト項目のアクセス権一覧、とかが見れる。このオブジェクト (or このプロファイル) にどんなアクセス権ついてんのかなー、とかを調べるのに便利そう
こんな機能知らなかったゾ
パフォーマンス (8%)
大量のユーザ、レコードでも大丈夫なような設計
とのことです。基本的には 企業の規模に応じたレコードアクセス権の作成 のドキュメントに載っている内容が出題されると予想しています。あとは レコードアクセス権に関連して Salesforce 内部で実行される処理 もですかね。
他にはパフォーマンスというと、データスキュー とか スキニーテーブル といったキーワードが思い浮かぶのですが、そこらへんのことも出るんじゃないかな・・?あとは ディビジョン とか。ここら辺は Data Architecture and Management デザイナー の試験範囲のような気もしてますが、どうせ両方とも受けるのでこの機会に詳しく調べておきます。
試験対策:パフォーマンスについて
パフォーマンスについては 8% しか出題されないのにめっちゃ調べてしまいました。。。
プログラミング的共有 (25%)
Apex 共有とか、あとは controller クラスでの with sharing, without sharing キーワードとかが出てくるんですかね?
以前に誰かに visualforce の画面を作ってもらった際に、プロファイル毎に表示可否を判断するという処理を入れてくれた方がいたのですが、そんなのはいらないんだぜって指摘をしたのを思い出しました。オブジェクトへの参照権限がない場合には <apex:inputfield> とかは権限を考慮して良い感じに表示可否を判断してくれる。
とはいえ、本当に複雑なロジックで表示を制御したいときには下の方に書いてる Apex での CRUD 判定とか、VF でのグローバルなんとかを使います。あとで書き直す
with sharing と without sharing と inherited sharing
apex のクラス作るときに public with sharing [クラス名] とか書きますよね。あれのことです。
inherited sharing は winter '19 くらいから出てきた新しい機能。
早速試験にでるとかあるんですかね?いや、ない。(と、予想)
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_classes_keywords_sharing.htm
with sharing
ユーザのコンテキストで実行される
ただし、判断されるのはレコードレベルの共有
オブジェクトレベルの CRUD とか項目レベルセキュリティとかは関係なす
without sharing
システム管理者のコンテキストで実行される
ただし、判断されるのは (略
テストコード
runAs() の挙動はしらべておいた方が良いかも。(他の方のブログでも言及されてたので )
オブジェクトへの参照権限は考慮される?
たぶんされない。システム管理者のコンテキストで実行される
項目レベルセキュリティは考慮される?
されない
レコードレベルの共有は考慮される?
される
公開グループは?ロールは?
たぶんされない。システム管理者のコンテキストで実行される。
Apex を使用したレコードの共有
Apex を利用してレコードを共有する方法です。標準の共有機能だけではどうしても要件を満たせない場合に利用します。たとえば「このボタンを押したタイミングでこのユーザにアクセス権を与える!」とか、あとは一定の法則の共有ルールを大量に作らないといけないとき、その他、共有先のユーザなりグループが特定の条件で変わるとき、とかですかね。。実際に業務で経験したのは、「特定のコード値を持つレコードは同一のレコード値を持つユーザに参照権を与える」とかです。
詳しくは こちら。
Apex でレコードの共有を行うには、オブジェクト毎に用意されている専用のオブジェクトにレコードを追加することで管理します。専用のオブジェクトの API 参照名ってのはあらかじめ決まっていて、以下の通りとなります。
標準オブジェクト:[API参照名]Share
たとえば Account (取引先) だったら、AccountShare
Opportunity (商談) だったら、OpportunityShare とかです。
カスタムオブジェクト:[API参照名]__Share
hoge__c だったら、hoge__Share になるということです。
普段はあまり意識することはあまりないですが、カスタムオブジェクトを画面ぽちぽちで作ったタイミングで、このようなオブジェクトも実は自動的に作られていた、ということなんですね。
ちなみに、上記2種類のオブジェクトはたしか上級デベロッパーの試験範囲でもありました。追加するレコードの内容は「SFID が XX のレコードをどのユーザ(もしくは公開グループ)に共有して、アクセスレベルは YY ですよ」ってのを定義できます。
詳しくは ここ を参照してください。サンプルコードを見ると、わかりやすいです。
Apex からの CRUD / 項目レベルセキュリティの判定
Visualforce
https://developer.salesforce.com/page/Enforcing_CRUD_and_FLS
visualforce で判定したいときはグローバル差し込み項目を利用します。{!$ObjectType.Contact.fields.Name.Accessible} のような書き方で判定できます。
上記リンクを参照。
※なお、FLS = Field Level Security = 項目レベルセキュリティ のことです。
apex
Apex から判定したいときは、schema クラスのメソッドを利用します。
!Schema.sObjectType.[API参照名].fields.Name.isAccessible()
みたいな書き方。上記リンク参照。
このやり方の他に、Spring `19 からベータ版の機能で、SOQL からも項目レベルセキュリティが確認できる機能が登場しました。Platform Developer のリリース試験 でも取り上げられている内容です。ベータ版の機能なので試験にはたぶんでない気もしますが、せっかくなので記録として残しておきます。
今までは以下のような書き方でした。
code: java
if (Schema.SObjectType.Contact.isAccessible()
&& Schema.SObjectType.Contact.fields.Name.isAccessible()
&& Schema.SObjectType.Contact.fields.Secret_Key__c.isAccessible()){
List<Contact> results = SELECT id, Name, Secret_Key__c FROM Contact WHERE Id = :recordId;
if (!results.isEmpty()) {
result = results0;
}
} else{
throw new SecurityException('You don\'t have access to all contact fields required to use this API');
}
シンタックスハイライトがうまくいきません、、、、
それが、下記のような書き方もできるようになります。
SOQL の最後に WITH SECURITY_ENFORCED を書いているのがポイントです。
code: java
try{
results = SELECT id, Name, Secret_Key__c FROM Contact WHERE Id = :recordId WITH SECURITY_ENFORCED;
}catch(QueryException e){
throw new SecurityException('You don\'t have access to all contact fields required to use this API');
}
if (!results.isEmpty()) {
result = results0;
} else {
return result;
}
inputfield と inppttext の違い
visualforce を描くときの注意点ですね。
inputfield:オブジェクトの項目もろもろが考慮されたテキストボックス (もちろん、CRUD が考慮される)
inputtext:ただのテキストボックス
受験後の感想
無事に合格しましたが、難しかったです・・・。試験中で選択肢として書かれている内容は全部正解のように思えるものが多数で、かなり迷いました。おそらくは、宣言的共有でも実装できる内容ってのはプログラミング共有でも実現できるので、実装可否でいう意味だとどちらも正解になるんじゃないかな、っていうことなのかと。なので、単純に「こういう機能があるんだなぁ」レベルの知識では合格にはならなくて、宣言的共有で実装するのが適しているパターン、プログラミング共有で実装するのが適しているパターンを知るってのが合格する上で重要なんじゃないかなぁ、と感じました。
あ、あとパフォーマンスについては 40% くらいしか取れなかったので参考にしないでください。笑
以上。
#資格試験
Salesforce 認定 Sharing and Visiblity デザイナー